#include <gtk/gtk.h>
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>


#define DBUS_SERVICE_KOPETE      "org.kde.kopete"
#define DBUS_PATH_KOPETE         "/Kopete"
#define DBUS_INTERFACE_KOPETE    "org.kde.Kopete"

DBusGConnection *bus;
DBusGProxy *dbus_proxy;
GError *error = NULL;

GtkWidget *list;
GList *listnodes;


enum
{
	COL_NAME = 0,
	COL_MSG,
	NUM_COLS
};


typedef struct {
	gchar *id;
	gchar *msg;
	gboolean inlist;
	GtkListStore *store;
	GtkTreeIter iter;
} node;


typedef struct {
	GtkWidget *combo;
	GtkWidget *msg;
	GtkWidget *list;
} info;

info sel;


gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data){
	return ( FALSE );
}

void destroy (GtkWidget *widget, gpointer data){
	gtk_main_quit ();
}



static GtkWidget * create_and_fill_combo_box( void ){

	g_type_init ();

	gchar **name_list;
	gchar **name_list_ptr;
	GtkWidget *combo;
    
	GtkListStore *cmb_store;
	GtkTreeIter cmb_iter;
	GtkCellRenderer *rend;
	rend = gtk_cell_renderer_text_new ();
    
	GList *glist = NULL;    
    
	cmb_store = gtk_list_store_new (1, G_TYPE_STRING);
    
	combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL( cmb_store ));
    
	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combo), rend, TRUE);
	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(combo), rend, "text", 0);


	/* Get the bus */
	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
	if (bus == NULL) {
		g_printerr("Failed to open connection to bus: %s", error->message);
		g_error_free(error);
		return gtk_combo_box_new();
	}

	/* Create a proxy object for the bus driver */
	dbus_proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_KOPETE, DBUS_PATH_KOPETE, DBUS_INTERFACE_KOPETE);
    
	if (!dbus_proxy) {
		g_printerr("Couldn't connect to the Purple Service: %s", error->message);
		g_error_free(error);
		return gtk_combo_box_new();
	}

	if(dbus_g_proxy_call (dbus_proxy, "contacts", &error, G_TYPE_INVALID, G_TYPE_STRV, &name_list, G_TYPE_INVALID)){
		for (name_list_ptr = name_list; *name_list_ptr; name_list_ptr++){	    
			glist = g_list_insert_sorted( glist, g_strsplit(*name_list_ptr, ":", 3)[2], g_ascii_strcasecmp );
		}
		GList *li;
	
		for (li = glist; li != NULL; li = g_list_next(li)){
			gtk_list_store_append (cmb_store, &cmb_iter);
			gtk_list_store_set (cmb_store, &cmb_iter, 0, li->data, -1);
		}
		g_list_free(li);

	}
    
	g_strfreev (name_list);
	g_list_free( glist );
    
	return combo;
}


static void init_list(GtkWidget *list){

	GtkCellRenderer    *renderer;
	GtkListStore       *store;

	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list), -1, "Nombre", renderer, "text", COL_NAME, NULL);
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list), -1, "Mensaje",	renderer, "text", COL_MSG, NULL);
	
// 	column = gtk_tree_view_column_new_with_attributes("List Item", renderer, "text", LIST_ITEM, NULL);
// 	gtk_tree_view_append_column(GTK_TREE_VIEW (list), column);

	store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING);

	gtk_tree_view_set_model(GTK_TREE_VIEW (list), GTK_TREE_MODEL(store));

	g_object_unref(store);
}


gchar* getText(){
	gchar *mes; 
	GtkTextBuffer *buffer;
	GtkTextIter start;
	GtkTextIter end;
		    
	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sel.msg));
	gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER (buffer), &start);
	gtk_text_buffer_get_end_iter  (GTK_TEXT_BUFFER (buffer), &end);
    
	mes = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start, &end, TRUE); 
	return mes;    
}



void launch(gpointer n2){
	node *n= n2;
	gboolean borrado = FALSE, conectado=FALSE;
	gchar **lst_contact;
	gchar **l_ptr;
	gchar * aux, *id, *msg;
	GError *error = NULL;
	GtkListStore *store;
	GtkTreeIter  iter;
	gboolean inlist;
	
	id=n->id;
	msg=n->msg;
	store= n->store;
	iter=n->iter;
	inlist=n->inlist;
	
	g_print(" > Mensaje '%s' para %s\n", n->msg, id);
	
	while( inlist && !borrado){
		if(dbus_g_proxy_call (dbus_proxy, "contactsByFilter", &error, G_TYPE_STRING, "online", G_TYPE_INVALID, G_TYPE_STRV, &lst_contact, G_TYPE_INVALID)){
			for (l_ptr = lst_contact; *l_ptr && !conectado; l_ptr++){
				aux = g_strsplit(*l_ptr, ":", 3)[2];
				if(!g_ascii_strcasecmp(aux, id)){
					g_print("El contacto %s está conectado\n", id);
					conectado = TRUE;
				}			  
			}
		}
		g_print("Mensaje %s\n", msg);
		if(conectado){
			if(dbus_g_proxy_call (dbus_proxy, "sendMessage", &error, G_TYPE_STRING, id, G_TYPE_STRING, msg, G_TYPE_INVALID,  G_TYPE_INVALID)){
				inlist = FALSE;
			}
		}
		else{
			g_print("Entramos en espera\n");
			g_usleep(5000000);
			g_print("Salimos de la espera\n");
		}
	}
	gtk_list_store_remove(store, &iter);
}


static void append_item(GtkWidget *widget, gpointer entry){
	
	GtkListStore *store;
	GtkTreeIter  iter;
	gchar *mes, *per;
	GThread *hilo;

	node n;	
	
	mes = getText();
	g_print ("Texto: %s \n", mes);

	//Get contact id
	per = gtk_combo_box_get_active_text(sel.combo);
	g_print ("Texto: %s \n", per);
	
 	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
	
 	gtk_list_store_append (store, &iter);
 	gtk_list_store_set (store, &iter, COL_NAME, per, COL_MSG, mes, -1);
	
	n.id = per;
	n.msg = mes;
	n.inlist = TRUE;
	n.store = store;
	n.iter = iter;
	hilo = g_thread_create (launch, &n, FALSE, NULL);
  
	listnodes = g_list_append(listnodes, &n);
	
}

static void remove_item(GtkWidget *widget, gpointer selection){
	GtkListStore *store;
	GtkTreeModel *model;
	GtkTreeIter  iter;

	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (list)));
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));

	if (gtk_tree_model_get_iter_first(model, &iter) == FALSE) 
		return;

	if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection),&model, &iter)) {
	    gchar * name;
	    gtk_tree_model_get (model, &iter, COL_NAME, &name, -1);
	    g_print("cadena: %s\n", name);
	    gtk_list_store_remove(store, &iter);
	}
}




int main(int argc, char *argv[]) {
	
	GtkWidget *window;
	GtkWidget *lbl_message, *lbl_contact, *lbl_list;
	GtkWidget *cmb_contact;
	GtkWidget *btn_add;
	GtkWidget *txt_message, *scroll;
	GtkWidget *scroll2;
	
	GtkWidget *hb_contact;
	GtkWidget *hb_buttons;
	GtkWidget *vb_main;
	GtkWidget *sw;
	
	GtkTreeSelection *selection;
	
	gtk_init (&argc, &argv);
	g_thread_init(NULL);
	dbus_g_thread_init();

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	sw = gtk_scrolled_window_new(NULL, NULL);
	list = gtk_tree_view_new();
	
	
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);

	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
	gtk_container_add(GTK_CONTAINER (sw), list);

	
	/* labels */
	lbl_message = gtk_label_new( "Mensaje:" );
	lbl_contact = gtk_label_new( "Contacto:" );
	lbl_list = gtk_label_new( "Mensajes pendientes:");
	
	/* combo box */
	cmb_contact = create_and_fill_combo_box(); 
	
	/* buttons */
	btn_add = gtk_button_new_with_label( "Añadir" );

	/* text widget */
	scroll = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
	txt_message = gtk_text_view_new();
	gtk_container_add(GTK_CONTAINER (scroll), txt_message);

	init_list(list);
	selection  = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
	gtk_container_add(GTK_CONTAINER (scroll2), list);

	/* group boxes */
	hb_contact = gtk_hbox_new( FALSE, 5 );
	hb_buttons = gtk_hbox_new( TRUE, 5 );
	vb_main = gtk_vbox_new( FALSE, 5 );

	gtk_box_pack_start( GTK_BOX( hb_buttons ), btn_add, TRUE, TRUE, 0 );

	gtk_box_pack_start( GTK_BOX( hb_contact ), lbl_contact, TRUE, TRUE, 0 );

	gtk_box_pack_start( GTK_BOX( hb_contact ), cmb_contact, TRUE, TRUE, 0 );

	gtk_box_pack_start( GTK_BOX( vb_main ), hb_contact, TRUE, TRUE, 0 );
	gtk_box_pack_start( GTK_BOX( vb_main ), lbl_message, TRUE, TRUE, 5 );
	gtk_box_pack_start( GTK_BOX( vb_main ), scroll, TRUE, TRUE, 0 );

	gtk_box_pack_start( GTK_BOX( vb_main ), hb_buttons, TRUE, TRUE, 10 );
	gtk_box_pack_start( GTK_BOX( vb_main ), lbl_list, TRUE, TRUE, 10 );
	gtk_box_pack_start( GTK_BOX( vb_main ), sw, TRUE, TRUE, 0 );

	gtk_container_add( GTK_CONTAINER( window ), vb_main );
			

	gtk_signal_connect (GTK_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL);
	gtk_signal_connect (GTK_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
	gtk_signal_connect (GTK_OBJECT (btn_add), "clicked",G_CALLBACK ( append_item ) , selection);

	gtk_container_border_width (GTK_CONTAINER (window), 10);

	gtk_widget_show_all(window);
	
	sel.combo = cmb_contact;
	sel.msg = txt_message;
	sel.list = list;

	gtk_main ();

	return 0;
}
